﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.ComponentModel;

namespace Sample
{
  class CtrlModel:INotifyPropertyChanged
  {
    #region Members Variable
    private int m_Value1 = 0;
    private int m_Value2 = 0;
    private int m_ValueAdd = 0;
    #endregion

    #region Properties
    public int Value1
    {
      get { return m_Value1; }
      set { m_Value1 = value; }
    }
    public int Value2
    {
      get { return m_Value2; }
      set { m_Value2 = value; }
    }
    public int ValueAdd
    {
      get { return m_ValueAdd; }
      set 
      { 
        m_ValueAdd = value;
        OnPropertyChanged("ValueAdd");
      }
    }
    #endregion

    #region ctor
    public CtrlModel()
    {
    }
    #endregion

    //public void Add()
    //{
    //  this.ValueAdd = LogicModel.Instance.Add(m_Value1, m_Value2);
    //}

    #region Command
    CommandBase m_CmdBase = null;
    public ICommand cAdd
    {
      get
      {
        if (m_CmdBase == null)
        {
          m_CmdBase = new CommandBase(ExecuteAddCommand, CanExecuteAddCommand);
        }
        return m_CmdBase;
      }
    }
    public void ExecuteAddCommand(object sender)
    {
      this.ValueAdd = LogicModel.Instance.Add(m_Value1, m_Value2);
    }
    public bool CanExecuteAddCommand(object sender)
    {
      return true;
    }
    #endregion

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
      if (this.PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
  }

  public class CommandBase : ICommand
  {
    private Func<object, bool> _canExecute;
    private Action<object> _executeAction;
    private bool canExecuteCache;

    public CommandBase(Action<object> executeAction, Func<object, bool> canExecute)
    {
      this._executeAction = executeAction;
      this._canExecute = canExecute;
    }

    #region ICommand Members
    public bool CanExecute(object parameter)
    {
      bool tempCanExecute = _canExecute(parameter);
      canExecuteCache = tempCanExecute;
      return canExecuteCache;
    }
    private event EventHandler _canExecuteChanged;
    public event EventHandler CanExecuteChanged
    {
      add { this._canExecuteChanged += value; }
      remove { this._canExecuteChanged -= value; }
    }
    protected virtual void OnCanExecuteChanged()
    {
      if (this._canExecuteChanged != null)
        this._canExecuteChanged(this, EventArgs.Empty);
    }
    public void Execute(object parameter)
    {
      _executeAction(parameter);
    }
    #endregion
  }
}
